<?php
/**
 * GeTuiService.php
 *
 * @copyright   2023 thingsworld.com.cn - All Rights Reserved
 * @link        http://thingsworld.com.cn/
 * @author      stiffer.chen <chenl@thingsworld.com.cn>
 * @created     2023-02-27 19:21:45
 * @modified    2023-02-27 19:21:45
 *
 */

namespace App\Services\Push;

use App\Library\Logger;
use App\Models\Notification;
use App\Models\User\Cid;

class GeTuiService
{
    const API_URL = 'https://restapi.getui.com';
    const APP_KEY = 'uBHCG5w2Tl7bJBNaoItpM4';
    const APP_ID = 'pOxtEehIWd6BWKPEixLGn7';
    const APP_SECRET = 'IxT6LL3qWx7MDoTZjpttY5';
    const MASTER_SECRET = 'Hd8LEh3VHc7cVgpncFyNOA';

    private $notifyId;
    private $userIds;
    private $log = null;

    /**
     * 根据 user ID(多个)，确定cid
     * 根据 notify ID 确定发送内容
     * @param $userIds
     * @param $notifyId
     */
    public function __construct($userIds, $notifyId)
    {
        $this->userIds = $userIds;
        $this->notifyId = $notifyId;
        $this->log = new Logger('push/getui');
    }

    public function push()
    {
        $notifyId = $this->notifyId;
        $notify = Notification::find($notifyId);
        if (empty($notify)) {
            $this->log->error("{$notifyId} 无对应通知信息");
            return;
        }
        $notifyTitle = $notify->title;
        $notifyBusinessId = $notify->business_id;
        $notifyBusinessType = $notify->business_type;
        $notifyContent = $notify->content;
        $notifyStatus = $notify->status;
        $this->log->info("推送数据: ID: {$notifyId}, 当前状态: {$notifyStatus}, 标题: {$notifyTitle}, 业务ID: {$notifyBusinessId}, 业务类型: {$notifyBusinessType}, 内容: {$notifyContent}");

        $userIds = $this->userIds;
        if (!is_array($userIds)) {
            $userIds = explode(',', $userIds);
        }
        $deviceIds = Cid::query()->select(['device_id'])->whereIn('user_id', $userIds)->get()->pluck('device_id')->toArray();
        $this->log->info("device ids:");
        $this->log->info($deviceIds);
        if (empty($deviceIds)) {
            $this->log->error("推送失败, 无对应设备ID");
            return;
        }
        $content = [
            'title' => $notifyTitle,
            'content' => $notifyContent,
            'data' => [
                'notify_type' => $notifyBusinessType,
                'notify_id' => $notifyId,
                'business_id' => $notifyBusinessId,
                'status' => $notifyStatus
            ]
        ];
        foreach ($deviceIds as $deviceId) {
            $this->pushSingleToCid($deviceId, $content);
        }
    }

    private function pushSingleToIos($cid, $content)
    {
        $api = new \GTClient(self::API_URL, self::APP_KEY, self::APP_ID, self::MASTER_SECRET);
        $ios = new \GTIos();
        $ios->setType('notify');
        $ios->setAutoBadge('1');
        $ios->setPayload(json_encode($content));
        $ios->setApnsCollapseId('apnsCollapseId');

        $aps = new \GTAps();
        $aps->setContentAvailable(0);
        $aps->setSound('com.gexin.ios.silenc');
        $aps->setCategory('');
        $aps->setThreadId('');

        $alert = new \GTAlert();
        $alert->setTitle($content['title'] ?? '');
        $alert->setBody($content['content'] ?? '');
//        $alert->setActionLocKey("ActionLocKey");
//        $alert->setLocKey("LocKey");
//        $alert->setLocArgs(array("LocArgs1","LocArgs2"));
//        $alert->setLaunchImage("LaunchImage");
//        $alert->setTitleLocKey("TitleLocKey");
//        $alert->setTitleLocArgs(array("TitleLocArgs1","TitleLocArgs2"));
        $alert->setSubtitle("");
        $alert->setSubtitleLocKey("");
        // $alert->setSubtitleLocArgs(array("subtitleLocArgs1","subtitleLocArgs2"));
        $aps->setAlert($alert);
        $ios->setAps($aps);

        $pushChannel = new \GTPushChannel();
        $pushChannel->setIos($ios);

        $message = new \GTPushMessage();
        $message->setTransmission(json_encode($content));

        $push = new \GTPushRequest();
        $push->setRequestId(md5(date('YmdHis') . microtime()));
        $push->setCid($cid);
        $push->setPushChannel($pushChannel);
        $push->setPushMessage($message);
        try {
            $result = $api->pushApi()->pushToSingleByCid($push);
            $this->log->info("success");
            $this->log->info($result);
        } catch (\Exception $e) {
            $this->log->info("fail");
            $this->log->info($e->getMessage());
        }
    }

    private function pushSingleToAndroid($cid, $content)
    {
        $api = new \GTClient(self::API_URL, self::APP_KEY, self::APP_ID, self::MASTER_SECRET);
        $push = new \GTPushRequest();
        $push->setRequestId(md5(date('YmdHis') . microtime()));
        $message = new \GTPushMessage();
        $message->setTransmission(json_encode($content));
        $push->setPushMessage($message);
        $push->setCid($cid);
        $this->log->info("target cid: {$cid}");
        // $push->setCidList([$this->cid]); // will be throw exception
        $result = $api->pushApi()->pushToSingleByCid($push);
        $this->log->info('push result');
        $this->log->info($result);
    }

    public function pushSingleToCid($cid, $content)
    {
        $this->log->info("开始推送");
        $this->log->info("设备ID: {$cid}");
        $this->log->info("内容: " . var_export($content, true));

        $cidData = Cid::query()->where('device_id', $cid)->first();
        if (empty($cidData)) {
            $this->log->info("推送失败，设备ID未上报");
            return;
        }
        $platform = strtolower($cidData->platform);
        if ($platform == 'ios') {
            $this->pushSingleToIos($cid, $content);
        }
        if ($platform == 'android') {
            $this->pushSingleToAndroid($cid, $content);
        }
    }
}